package com.jie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jie.constant.Constant;
import com.jie.constant.RedisKey;
import com.jie.dto.GroupDTO;
import com.jie.dto.UserDetailDTO;
import com.jie.enums.ResultCode;
import com.jie.exception.BusinessException;
import com.jie.mapper.FriendImMapper;
import com.jie.mapper.GroupUserMapper;
import com.jie.pojo.FriendIm;
import com.jie.pojo.GroupIm;
import com.jie.mapper.GroupImMapper;
import com.jie.pojo.GroupUser;
import com.jie.service.GroupImService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jie.service.GroupUserService;
import com.jie.util.BeanUtils;
import com.jie.util.UserUtils;
import com.jie.vo.GroupImVO;
import com.jie.vo.GroupInviteVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 *  群管理
 * </p>
 *
 * @author xiaojie
 * @since 2023-11-01
 */
@Slf4j
@CacheConfig(cacheNames = RedisKey.IM_CACHE_GROUP)
@Service
@AllArgsConstructor
public class GroupImServiceImpl extends ServiceImpl<GroupImMapper, GroupIm> implements GroupImService {
    @Autowired
    private GroupUserMapper groupUserMapper;
    @Autowired
    private FriendImMapper friendImMapper;
    @Autowired
    private GroupUserService groupUserService;

    /**
     * 创建群
     * @param vo
     * @return dto
     */
    @Override
    public GroupDTO createGroup(GroupImVO vo) {
        //获取当前创建群的对象
        UserDetailDTO user = UserUtils.getLoginUser();
        // 保存群组数据
        GroupIm group = BeanUtils.copyProperties(vo, GroupIm.class);
        group.setOwnerId(user.getUserInfoId());
        this.save(group);
        //手动将当前对象添加为此群的群主并拉入群
        // 把群主加入群
        GroupUser groupUser = new GroupUser();
        groupUser.setGroupId(group.getId());
        groupUser.setReceiverId(user.getUserInfoId());
        groupUser.setHeadImage(user.getAvatar());
        groupUser.setAliasName(StringUtils.isEmpty(vo.getAliasName()) ? user.getNickname() : vo.getAliasName());
        groupUserMapper.insert(groupUser);
        vo.setId(group.getId());
        vo.setAliasName(groupUser.getAliasName());
        log.info("用户:{},创建群聊，群聊id:{},群聊名称:{}",user.getUsername(),group.getId(), group.getGroupName());

        return BeanUtils.copyProperties(vo, GroupDTO.class);
    }

    /**
     * 邀请好友进入群聊
     * @param vo
     */
    @Override
    public void invite(GroupInviteVO vo) {
        UserDetailDTO user = UserUtils.getLoginUser();
        GroupIm group = this.getById(vo.getGroupId());
        if (group == null) {
            throw new BusinessException(ResultCode.PROGRAM_ERROR.getCode(), "群聊不存在");
        }
        // 群聊人数校验
        List<GroupUser> members = groupUserMapper.selectList(new LambdaQueryWrapper<GroupUser>().eq(GroupUser::getGroupId, vo.getGroupId()));
        //获取在群人数
        long size = members.stream().filter(m -> !(m.getIsDelete()==1)).count();
        if (vo.getFriendIds().size() + size > Constant.MAX_GROUP_MEMBER) {
            throw new BusinessException(ResultCode.PROGRAM_ERROR.getCode(), "群聊人数不能大于" + Constant.MAX_GROUP_MEMBER + "人");
        }
        // 找出好友信息
        List<FriendIm> friends = friendImMapper.selectList(new LambdaQueryWrapper<FriendIm>().eq(FriendIm::getInitiatorId, user.getId()));
        List<FriendIm> friendsList = vo.getFriendIds().stream()
                .map(id -> friends.stream().filter(f -> f.getReceiverId().equals(id)).findFirst().get())
                .collect(Collectors.toList());
        if (friendsList.size() != vo.getFriendIds().size()) {
            throw new BusinessException(ResultCode.PROGRAM_ERROR.getCode(), "部分用户不是您的好友，邀请失败");
        }
        // 批量保存成员数据
        List<GroupUser> groupMembers = friendsList.stream().map(f -> {
            Optional<GroupUser> optional = members.stream().filter(m -> m.getReceiverId().equals(f.getReceiverId())).findFirst();
            GroupUser groupUser = optional.orElseGet(GroupUser::new);
            groupUser.setGroupId(vo.getGroupId());
            groupUser.setReceiverId(f.getReceiverId());
            groupUser.setAliasName(f.getNickName());
            groupUser.setHeadImage(f.getAvatar());
            return groupUser;
        }).collect(Collectors.toList());
        if (!groupMembers.isEmpty()) {
            groupUserService.saveOrUpdateBatch(group.getId(), groupMembers);
        }
        log.info("邀请进入群聊，群聊id:{},群聊名称:{},被邀请用户id:{}", group.getId(), group.getGroupName(), vo.getFriendIds());
    }
}
